package mgr

// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.

import (
	"context"
	"encoding/json"
	"errors"
	"strings"
	"time"

	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/ferror"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/gorms"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/resultcode"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/xids"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/enums"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/gqlgen/mgr/gmodel"
	model1 "gitee.com/shiqiyue/xd-bi/internal/modules/cr/model"
	"gorm.io/datatypes"
	"gorm.io/gorm"
)

func (r *mutationResolver) InsertReport(ctx context.Context, req gmodel.InsertReportReq) (bool, error) {
	// 参数校验
	db := gorms.GetDb(ctx, r.Db)
	isCodeValid, err := r.ReportSrv.IsCodeValid(ctx, db, req.Code, nil)
	if err != nil {
		return false, err
	}
	if !isCodeValid {
		return false, errors.New("编号已存在")
	}
	err = r.ReportSrv.InsertReport(ctx, db, req)
	if err == nil {
		return true, nil
	}
	return false, err
}

func (r *mutationResolver) UpdateReport(ctx context.Context, req gmodel.UpdateReportReq) (bool, error) {
	// 参数校验
	db := gorms.GetDb(ctx, r.Db)
	isCodeValid, err := r.ReportSrv.IsCodeValid(ctx, db, req.Code, &req.ReportID)
	if err != nil {
		return false, err
	}
	if !isCodeValid {
		return false, errors.New("编号已存在")
	}

	err = db.Transaction(func(tx *gorm.DB) error {
		updateParam := map[string]interface{}{}
		updateParam["type"] = req.Type
		updateParam["code"] = req.Code
		updateParam["display_type"] = req.DisplayType
		updateParam["data_access_support"] = req.DataAccessSupport
		updateParam["name"] = req.Name
		updateParam["page_support"] = req.PageSupport
		updateParam["updated_at"] = time.Now()
		updateParam["show_summary"] = req.ShowSummary
		err := r.ReportSrv.UpdateByUnionId(ctx, tx, req.ReportID, updateParam)
		if err != nil {
			return err
		}
		return nil
	})
	if err == nil {
		return true, nil
	}
	return false, err
}

func (r *mutationResolver) EnableReport(ctx context.Context, reportID string) (bool, error) {
	db := gorms.GetDb(ctx, r.Db)
	var err = r.ReportSrv.ChangeStatus(ctx, db, reportID, enums.REPORT_STATUS_ACTIVE)
	if err != nil {
		return false, err
	}
	return true, nil
}

func (r *mutationResolver) DismissReport(ctx context.Context, reportID string) (bool, error) {
	db := gorms.GetDb(ctx, r.Db)
	err := r.ReportSrv.ChangeStatus(ctx, db, reportID, enums.REPORT_STATUS_DISMISS)
	if err != nil {
		return false, err
	}
	return true, nil
}

func (r *mutationResolver) UpdateReportForm(ctx context.Context, req gmodel.UpdateReportFormReq) (bool, error) {
	db := gorms.GetDb(ctx, r.Db)
	err := db.Transaction(func(tx *gorm.DB) error {
		err := r.ReportFormSrv.RemoveByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return err
		}
		var forms = []model1.ReportForm{}
		for i, item := range req.FormItems {
			form := model1.ReportForm{
				ReportFormId:    xids.GetXid(ctx),
				ReportId:        req.ReportID,
				Type:            item.Type,
				Name:            item.Name,
				AttributeName:   item.AttributeName,
				DictCategoryId:  item.DictCategoryID,
				ReturnAllDict:   item.ReturnAllDict,
				ExtraConfig:     item.ExtraConfig,
				IndexNum:        &i,
				DefaultValue:    item.DefaultValue,
				Required:        item.Required,
				QueryReportCode: item.QueryReportCode,
			}
			forms = append(forms, form)
		}
		if len(forms) > 0 {
			err = r.ReportFormSrv.Insert(ctx, tx, forms)
			return err
		}
		return nil
	})
	if err != nil {
		return false, err
	}
	return true, nil
}

func (r *mutationResolver) TestReport(ctx context.Context, req gmodel.TestReportReq) (*gmodel.TestReportResult, error) {
	db := gorms.GetDb(ctx, r.Db)
	executeReport, err := r.ReportSrv.ExecuteReport(ctx, db, req.Code, req.Params)
	if err != nil {
		return nil, ferror.WrapCode(resultcode.FAIL, err)
	}
	return &gmodel.TestReportResult{
		List:      executeReport.List,
		Count:     executeReport.Count,
		SQL:       executeReport.Sql,
		CountSQL:  executeReport.CountSql,
		Aggregate: executeReport.Aggregate,
		Detail:    executeReport.Detail,
	}, nil
}

func (r *mutationResolver) CopyReport(ctx context.Context, req gmodel.CopyReportReq) (bool, error) {
	db := gorms.GetDb(ctx, r.Db)
	err := db.Transaction(func(tx *gorm.DB) error {
		isCodeValid, err := r.ReportSrv.IsCodeValid(ctx, db, req.Code, nil)
		if err != nil {
			return err
		}
		if !isCodeValid {
			return errors.New("编号已存在")
		}
		// report
		report := &model1.Report{}
		err = r.ReportSrv.GetByUnionId(ctx, tx, req.ReportID, report)
		if err != nil {
			return ferror.Wrap("报表不存在", err)
		}
		report.ID = 0
		report.ReportId = xids.GetXid(ctx)
		report.Code = req.Code
		err = r.ReportSrv.Insert(ctx, tx, report)
		if err != nil {
			return err
		}
		// form
		forms, err := r.ReportFormSrv.GetByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return err
		}
		if forms != nil && len(forms) > 0 {
			for i, _ := range forms {
				forms[i].ID = 0
				forms[i].ReportFormId = xids.GetXid(ctx)
				forms[i].ReportId = report.ReportId

			}
			err := r.ReportFormSrv.Insert(ctx, tx, forms)
			if err != nil {
				return err
			}
		}
		//result
		resultColumns, err := r.ReportResultColumnSrv.GetByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return err
		}
		if resultColumns != nil && len(resultColumns) > 0 {
			for i, _ := range resultColumns {
				resultColumns[i].ID = 0
				resultColumns[i].ReportResultColumnId = xids.GetXid(ctx)
				resultColumns[i].ReportId = report.ReportId
			}
			err := r.ReportResultColumnSrv.Insert(ctx, tx, resultColumns)
			if err != nil {
				return err
			}
		}
		// sql report
		sqlReport, err := r.SqlReportSrv.GetByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return err
		}
		if sqlReport != nil {
			sqlReport.ReportId = report.ReportId
			sqlReport.ID = 0
			sqlReport.SqlReportId = ""
			err := r.SqlReportSrv.Insert(ctx, tx, sqlReport)
			if err != nil {
				return err
			}
		}
		// aggregate report
		aggregates, err := r.ReportAggregateSrv.GetByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return err
		}
		if aggregates != nil && len(aggregates) > 0 {
			for i, _ := range aggregates {
				aggregates[i].ID = 0
				aggregates[i].ReportAggregateId = xids.GetXid(ctx)
				aggregates[i].ReportId = report.ReportId

			}
			err := r.ReportAggregateSrv.Insert(ctx, tx, aggregates)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return false, err
	}
	return true, nil
}

func (r *mutationResolver) UpdateReportSQL(ctx context.Context, req gmodel.UpdateReportSQL) (bool, error) {
	db := gorms.GetDb(ctx, r.Db)
	err := r.SqlReportSrv.Update(ctx, db, req)
	if err != nil {
		return false, err
	}
	return true, nil
}

func (r *mutationResolver) UpdateReportResultColumns(ctx context.Context, req gmodel.UpdateReportResultColumnReq) (bool, error) {
	db := gorms.GetDb(ctx, r.Db)
	err := db.Transaction(func(tx *gorm.DB) error {
		err := r.ReportResultColumnSrv.RemoveByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return err
		}
		var columns = []model1.ReportResultColumn{}
		for i, item := range req.Items {
			if item.JumpParams == nil {
				item.JumpParams = make([]*model1.ReportResultColumnJumpParam, 0)
			}
			jumpparam := datatypes.JSON{}
			bytes, err := json.Marshal(item.JumpParams)
			if err != nil {
				return err
			}
			err = jumpparam.UnmarshalJSON(bytes)
			if err != nil {
				return err
			}
			column := model1.ReportResultColumn{
				ReportResultColumnId: xids.GetXid(ctx),
				ReportId:             req.ReportID,
				Type:                 item.Type,
				Name:                 item.Name,
				AttributeName:        item.AttributeName,
				DictCategoryId:       item.DictCategoryID,
				ExtraConfig:          item.ExtraConfig,
				IsShow:               item.IsShow,
				IndexNum:             &i,
				EmptyValueFontColor:  item.EmptyValueFontColor,
				EmptyValue:           item.EmptyValue,
				FontColor:            item.FontColor,
				IsJump:               item.IsJump,
				JumpType:             item.JumpType,
				JumpTarget:           item.JumpTarget,
				JumpParams:           &jumpparam,
				JumpMode:             item.JumpMode,
			}
			columns = append(columns, column)
		}
		if len(columns) > 0 {
			err = r.ReportResultColumnSrv.Insert(ctx, tx, columns)
			return err
		}
		return nil
	})
	if err != nil {
		return false, ferror.WrapWithCode("更新返回信息异常", resultcode.FAIL, err)
	}
	return true, nil
}

func (r *mutationResolver) UpdateReportAggregate(ctx context.Context, req gmodel.UpdateReportAggregateReq) (bool, error) {
	db := gorms.GetDb(ctx, r.Db)
	err := db.Transaction(func(tx *gorm.DB) error {
		err := r.ReportAggregateSrv.RemoveByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return ferror.WrapWithCode("删除聚合信息异常", resultcode.FAIL, err)
		}
		var aggregates = []model1.ReportAggregate{}
		for _, item := range req.Items {
			t := strings.ReplaceAll(item.AttributeName, " ", "")
			if t == "" || item.ConnectReportID == "" {
				continue
			}
			aggregate := model1.ReportAggregate{
				ReportAggregateId: xids.GetXid(ctx),
				ReportId:          req.ReportID,
				ConnectReportId:   item.ConnectReportID,
				AttributeName:     item.AttributeName,
			}
			aggregates = append(aggregates, aggregate)
		}
		if len(aggregates) > 0 {
			err = r.ReportAggregateSrv.Insert(ctx, tx, aggregates)
			return err
		}
		return nil
	})
	if err != nil {
		return false, ferror.WrapWithCode("更新聚合信息异常", resultcode.FAIL, err)
	}
	return true, nil
}

// Mutation returns MutationResolver implementation.
func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }

type mutationResolver struct{ *Resolver }
